﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.ServiceModel.Dispatcher;
using System.Text;
using System.Threading.Tasks;

namespace ebMS3dotnet.Core.Configuration
{
    class ebMS3ConfigurationSection : ConfigurationSection
    {

        [ConfigurationProperty("endpoints", IsDefaultCollection = true)]
        public EndpointCollection Endpoints
        {
            get
            {
                return (EndpointCollection)base["endpoints"];
            }
        }

        [ConfigurationProperty("filters", Options = ConfigurationPropertyOptions.None)]
        public FilterElementCollection Filters
        {
            get
            {
                return (FilterElementCollection)base["filters"];
            }
        }
        [ConfigurationProperty("pModes", IsDefaultCollection = true)]
        public PModeCollection PModes
        {
            get
            {
                return (PModeCollection)base["pModes"];
            }
        }

        [ConfigurationProperty("processors", Options = ConfigurationPropertyOptions.None)]
        public ProcessorElementCollection Processors
        {
            get
            {
                return (ProcessorElementCollection)base["processors"];
            }
        }

        internal MessageFilterTable<IOneWayProcessor> CreateFilterTable()
        {
            MessageFilterTable<IOneWayProcessor> filterTable = new MessageFilterTable<IOneWayProcessor>();

            foreach (ProcessorElement processor in Processors)
            {
                FilterElement filter = Filters[processor.FilterName];
                filterTable.Add(filter.CreateFilter(null, Filters), CreateProcessor(processor.ProcessorType));
            }
            return filterTable;
        }

        private IOneWayProcessor CreateProcessor(Type type)
        {
            var processor = Activator.CreateInstance(type);
            if (!(processor is IOneWayProcessor))
                throw new ConfigurationErrorsException("A processor must implement IOneWayProcessor");
            return (IOneWayProcessor)processor;
        }

        internal static ebMS3ConfigurationSection GetSection()
        {
            ebMS3ConfigurationSection configSection = (ebMS3ConfigurationSection)ConfigurationManager.GetSection("ebMS3dotnet");
            if (configSection == null)
                throw new ConfigurationErrorsException("The configuration section ebMS3dotnet could not be found.");
            return configSection;
        }
    }
}
